package cn.iocoder.yudao.module.project.controller.admin.electronicscalemanage;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.NumberUtil;
import cn.iocoder.yudao.framework.common.exception.ServerException;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.project.controller.admin.tcp.vo.SendVO;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;

import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.*;
import java.io.IOException;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;

import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
import static cn.iocoder.yudao.module.project.config.projectDefine.HTTP_STATUS.ERROR_STATUS;
import static cn.iocoder.yudao.module.project.config.projectDefine.STATUS.STATUS_0;
import static cn.iocoder.yudao.module.project.config.projectDefine.STATUS.STATUS_1;

import cn.iocoder.yudao.module.project.controller.admin.electronicscalemanage.vo.*;
import cn.iocoder.yudao.module.project.dal.dataobject.electronicscalemanage.ElectronicScaleManageDO;
import cn.iocoder.yudao.module.project.service.electronicscalemanage.ElectronicScaleManageService;

@Tag(name = "管理后台 - 电子秤管理")
@RestController
@RequestMapping("/project/electronic-scale-manage")
@Validated
public class ElectronicScaleManageController {

    @Resource
    private ElectronicScaleManageService electronicScaleManageService;

    @PostMapping("/create")
    @Operation(summary = "创建电子秤管理")
    // @PreAuthorize("@ss.hasPermission('project:electronic-scale-manage:create')")
    public CommonResult<Long> createElectronicScaleManage(@Valid @RequestBody ElectronicScaleManageSaveReqVO createReqVO) {
        if (StringUtils.isBlank(createReqVO.getRemark())) {
            createReqVO.setRemark("");
        }
        if (null == createReqVO.getStatus()) {
            createReqVO.setStatus(STATUS_0);
        }
        return success(electronicScaleManageService.createElectronicScaleManage(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新电子秤管理")
    // @PreAuthorize("@ss.hasPermission('project:electronic-scale-manage:update')")
    public CommonResult<Boolean> updateElectronicScaleManage(@Valid @RequestBody ElectronicScaleManageSaveReqVO updateReqVO) {
        electronicScaleManageService.updateElectronicScaleManage(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除电子秤管理")
    @Parameter(name = "id", description = "编号", required = true)
    // @PreAuthorize("@ss.hasPermission('project:electronic-scale-manage:delete')")
    public CommonResult<Boolean> deleteElectronicScaleManage(@RequestParam("id") Long id) {
        electronicScaleManageService.deleteElectronicScaleManage(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得电子秤管理")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    // @PreAuthorize("@ss.hasPermission('project:electronic-scale-manage:query')")
    public CommonResult<ElectronicScaleManageRespVO> getElectronicScaleManage(@RequestParam("id") Long id) {
        ElectronicScaleManageDO electronicScaleManage = electronicScaleManageService.getElectronicScaleManage(id);
        return success(BeanUtils.toBean(electronicScaleManage, ElectronicScaleManageRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得电子秤管理分页")
    // @PreAuthorize("@ss.hasPermission('project:electronic-scale-manage:query')")
    public CommonResult<PageResult<ElectronicScaleManageRespVO>> getElectronicScaleManagePage(@Valid ElectronicScaleManagePageReqVO pageReqVO) {
        PageResult<ElectronicScaleManageDO> pageResult = electronicScaleManageService.getElectronicScaleManagePage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, ElectronicScaleManageRespVO.class));
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出电子秤管理 Excel")
    // @PreAuthorize("@ss.hasPermission('project:electronic-scale-manage:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportElectronicScaleManageExcel(@Valid ElectronicScaleManagePageReqVO pageReqVO,
                                                 HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<ElectronicScaleManageDO> list = electronicScaleManageService.getElectronicScaleManagePage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "电子秤管理.xls", "数据", ElectronicScaleManageRespVO.class,
                BeanUtils.toBean(list, ElectronicScaleManageRespVO.class));
    }




    @PostMapping("/updateStatus")
    @Operation(summary = "更新电子秤启用停用状态")
    // @PreAuthorize("@ss.hasPermission('project:electronic-scale-manage:update')")
    public CommonResult<Boolean> updateStatus(@RequestBody ElectronicScaleManageSaveReqVO updateReqVO) {
        electronicScaleManageService.updateStatus(updateReqVO);
        return success(true);
    }

    @GetMapping("/onlineList")
    @Operation(summary = "获得在线的电子秤列表")
    // @PreAuthorize("@ss.hasPermission('project:electronic-scale-manage:query')")
    public CommonResult<List<ElectronicScaleManageRespVO>> getOnlineList(@Valid ElectronicScaleManagePageReqVO pageReqVO) {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        pageReqVO.setStatus(STATUS_1);
        List<ElectronicScaleManageDO> list = electronicScaleManageService.getElectronicScaleManagePage(pageReqVO).getList();

        return success(BeanUtils.toBean(list, ElectronicScaleManageRespVO.class));
    }

    /**
     * 获取电子秤返回的重量
     * @param sendVO
     * @return
     * @throws IOException
     */
    @PostMapping("/weight")
    public CommonResult<Double> weight(@RequestBody SendVO sendVO) throws IOException {
        String ip = sendVO.getIp();
        Integer port = sendVO.getPort();

        //ip = "119.3.72.36";
        //port = 8083;

        // String msg = sendVO.getMsg();
        Socket socket = new Socket();
        SocketAddress socketAddress = new InetSocketAddress(ip ,port); //获取sockaddress对象
        socket.setKeepAlive(true);
        socket.connect(socketAddress, 2000);
        // 设置最大连接超时时间，超过此时间，无响应则断开连接
        socket.setSoTimeout(2000);
        System.out.println("连接服务器成功：" + socket);

        String msg = "RN";
        Double weight = null;

        try {
            // 发送消息
            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
            out.println(msg);

            // 接收消息
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String str = in.readLine();

            //str = "20g";

            // 解析电子秤中的重量
            str = str.trim();
            String result = "";
            if (str != null && !"".equals(str)) {
                String[] splitArr = str.split(",");
                if (null != splitArr && splitArr.length > 0) {
                    for (String s : splitArr) {
                        if (s.contains("g")) {
                            result = s.replace("g", "").trim();
                        }
                    }
                }
            }
            if (StringUtils.isNotBlank(result) && NumberUtil.isNumber(result)) {
                weight = Double.valueOf(result);
                return success(weight);
            }


        } catch (IOException e) {
            e.printStackTrace();
            return error(ERROR_STATUS, "电子秤通讯异常");
        } finally {
            // 关闭连接
            socket.close();
        }

        return success(weight);
    }

    /**
     * 获取当前用户选择的电子秤
     * @return
     */
    @GetMapping("/getUsedScale")
    public CommonResult getUsedScale(){
        ElectronicScaleManageDO usedScale = electronicScaleManageService.getUsedScale(SecurityFrameworkUtils.getLoginUserId());
        return CommonResult.success(usedScale);
    }

    /**
     * 设置当前用户选择的电子秤
     * @param scale
     * @return
     */
    @PostMapping("/updateUsedScale")
    public CommonResult updateUsedScale(@RequestBody ElectronicScaleManageDO scale){
        Boolean column = electronicScaleManageService.updateUsedScale(SecurityFrameworkUtils.getLoginUserId(), scale);
        return CommonResult.success(column);
    }

    /**
     * 获取电子秤通讯状态
     *
     * @param sendVO
     * @return
     * @throws IOException
     */
    @PostMapping("/check")
    public CommonResult<Boolean> check(@RequestBody SendVO sendVO) {
        String ip = sendVO.getIp();
        Integer port = sendVO.getPort();

        //ip = "119.3.72.36";
        //port = 8083;

        Socket socket = null;
        try {
            socket = new Socket();
            SocketAddress socketAddress = new InetSocketAddress(ip, port); // 获取sockaddress对象
            socket.setKeepAlive(true);
            socket.connect(socketAddress, 2000);
            // 设置最大连接超时时间，超过此时间，无响应则断开连接
            socket.setSoTimeout(2000);

        } catch (IOException e) {
            // return error(ERROR_STATUS, "电子秤通讯异常");
            return success(false);
        } finally {
            // 关闭连接
            IoUtil.close(socket);
        }
        return success(true);
    }

}
